#pragma once
#include <string>
#include <memory>
#include "fields.hpp"
#include <functional>


/**通讯类型抽象实现 */
namespace Json_rpc{

    
    class BaseMessage
    {
    public:
        using ptr = std::shared_ptr<BaseMessage>;

        virtual ~BaseMessage(){}
        //设置id
        virtual void setId(const std::string &id)
        {
            _rid=id;
        }
        //获取id
        virtual std::string id(){return _rid;}
        //设置消息类型
        virtual void setMType(MType mtype)
        {
            _mtype=mtype;
        }
        //获取消息类型
        virtual MType mtype(){return _mtype;}
        //序列化
        virtual std::string serialize() =0;
        //反序列化
        virtual bool unserialize(const std::string &msg) =0;
        //检查
        virtual bool check()=0;
    private:
        MType _mtype;
        std::string _rid;
    };
    
    class BaseBuffer
    {
    public:
        using ptr = std::shared_ptr<BaseBuffer>;
        //获取缓冲区已有数据
        virtual size_t readableSize()=0;
        //尝试取出4字节数据 不删除数据
        virtual int32_t peeKInt32()=0;
        //从缓冲区删除4字节数据
        virtual void retrieveInt32()=0;
        //尝试取出4字节数据并且删除数据
        virtual int32_t readInt32()=0;
        //从缓冲区取出指定长度数据
        virtual std::string retrieveAsString(size_t len)=0;
    };
    
    class BaseProtocol
    {
    public:
        using ptr = std::shared_ptr<BaseProtocol>;

        //检查缓冲区是否可以处理数据
        virtual bool canProcessed(const BaseBuffer::ptr &buf)=0;
        //对接收的消息进行处理并返回消息
        virtual bool onMessage(const BaseBuffer::ptr &buf,BaseMessage::ptr &msg)=0;
        //对消息进行序列化
        virtual std::string serialize(const BaseMessage::ptr &msg)=0;
    };

    class BaseConnection
    {
    public:
        using ptr = std::shared_ptr<BaseConnection>;
        //发送数据
        virtual void send(const BaseMessage::ptr &msg)=0;
        //关闭连接
        virtual void shutdown()=0;
        //判断连接是否正常
        virtual bool connected()=0;
    };
    
    using ConnectionCallback = std::function<void(const BaseConnection::ptr &)>;
    using CloseCallback = std::function<void(const BaseConnection::ptr &)>;
    using MessageCallback = std::function<void(const BaseConnection::ptr &,BaseMessage::ptr &)>;
    class BaseServer
    {
    public:
        using ptr = std::shared_ptr<BaseServer>;
        //设置连接回调函数
        virtual void setConnectionCallback(const ConnectionCallback& cb){
            _cb_connection=cb;
        }
        //设置关闭连接回调函数
        virtual void setCloseCallback(const CloseCallback& cb){
            _cb_close=cb;
        }
        //设置消息回调函数
        virtual void setMessageCallback(const MessageCallback& cb){
            _cb_message=cb;
        }
        //服务器启动
        virtual void start()=0;
    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };
    
    class BaseClient
    {
    public:
        using ptr = std::shared_ptr<BaseClient>;
        //设置连接回调函数
        virtual void setConnectionCallback(const ConnectionCallback& cb){
            _cb_connection=cb;
        }
        //设置关闭连接回调函数
        virtual void setCloseCallback(const CloseCallback& cb){
            _cb_close=cb;
        }
        //设置消息回调函数
        virtual void setMessageCallback(const MessageCallback& cb){
            _cb_message=cb;
        }
        //建立连接
        virtual void connect()=0;
        //关闭连接
        virtual void shutdown()=0;
        //发送消息
        virtual bool send(const BaseMessage::ptr &msg)=0;
        //获取连接
        virtual BaseConnection::ptr connection() = 0;
        //判断连接是否正常
        virtual bool connected() = 0;
    protected:
        ConnectionCallback _cb_connection;
        CloseCallback _cb_close;
        MessageCallback _cb_message;
    };

}